Skip to content

feat(typescript): add optional builderCode to x402 client and server - #768

Open
ethanoroshiba wants to merge 6 commits into
mainfrom
ethanoroshiba/x402-builder-codes
Open

feat(typescript): add optional builderCode to x402 client and server#768
ethanoroshiba wants to merge 6 commits into
mainfrom
ethanoroshiba/x402-builder-codes

Conversation

@ethanoroshiba

@ethanoroshiba ethanoroshiba commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add optional builderCode on CdpX402Client and createX402Server to attach the x402 builder-code extension (client s, server a)
  • Independently of that option, every CdpX402Client and every EVM route on createX402Server now always attaches the SDK's own service code (cdp_sdk_client / cdp_sdk_server) to s, so on-chain activity from the CDP SDK is attributed regardless of whether a caller sets builderCode
  • Since @x402/core's extension merge treats server-declared builder-code fields as authoritative, a server that declares s would otherwise silently drop whatever the client's own extension(s) contributed for that field; CdpX402Client now reconciles the two after payload creation so both sides' codes survive
  • Omit builderCode → extension still carries the SDK's own code; invalid codes rejected at init/create
  • Docs, config schema, README, and unit + e2e coverage for inject / register / override / reconciliation paths

Test plan

  • Unit tests covering: client always registers the SDK's own service code (with/without a configured builderCode); server always advertises builder-code with the SDK's own code on EVM routes (with/without a configured app code); reconciliation correctly unions the client's and server's service codes when the server's declaration would otherwise clobber the client's; manual registerExtension/route extensions overrides still take precedence
  • E2E test verifies the CDP facilitator accepts a payment carrying the server's app code plus all three service codes (server, configured client, and the SDK's own) after reconciliation

@cb-heimdall

Copy link
Copy Markdown

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 0
Sum 1

@ethanoroshiba

Copy link
Copy Markdown
Contributor Author

Note on facilitator support: the CDP-hosted facilitator supports the builder-code extension, so app (a) and service (s) codes advertised/attached by createX402Server and CdpX402Client are encoded into the ERC-8021 Schema 2 calldata suffix at settlement. No self-hosted facilitator changes are needed to get attribution on the default path.

@ethanoroshiba
ethanoroshiba marked this pull request as ready for review July 29, 2026 21:37
const client = new CdpX402Client({ builderCode: "my_client" });
```

Service codes are only attached when the resource server advertises the `builder-code` extension in its `PaymentRequired` response — against servers that do not, the codes are dropped and the payment proceeds unattributed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think we should change this and always attribute the client regardless of the server, dont see a good reason to drop

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants